package org.beetl.sql.springboot.conf;


import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.beetl.sql.core.ExecuteContext;
import org.beetl.sql.core.Interceptor;
import org.beetl.sql.core.SQLManager;
import org.beetl.sql.ext.DBInitHelper;
import org.beetl.sql.ext.DebugInterceptor;
import org.beetl.sql.springboot.dynamic.DynamicRoutingDataSourceAndSqlManager;
import org.beetl.sql.starter.SQLManagerCustomize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;


@Configuration
@Slf4j
public class DatasourceConfig {


	@Autowired
	ApplicationContext ctx;

	@Bean(name = "h2Ds")
	public DataSource h2Datasource(Environment env) {
		HikariDataSource ds = new HikariDataSource();
		ds.setJdbcUrl(env.getProperty("spring.datasource.url"));
		ds.setUsername(env.getProperty("spring.datasource.username"));
		ds.setPassword(env.getProperty("spring.datasource.password"));
		ds.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
		ds.setMaximumPoolSize(2);
		DBInitHelper.executeSqlScript(ds,DatasourceConfig.class.getResourceAsStream("/db/schema-h2.sql"));
		return ds;
	}

	/**
	 * 初始化mysql，但仍然使用h2数据库作为例子，简化测试
	 * @param env
	 * @return
	 */
	@Bean(name = "mysqlDs")
	public DataSource mysqDatasource(Environment env) {
		HikariDataSource ds = new HikariDataSource();
		ds.setJdbcUrl(env.getProperty("spring.datasource.url"));
		ds.setUsername(env.getProperty("spring.datasource.username"));
		ds.setPassword(env.getProperty("spring.datasource.password"));
		ds.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
		ds.setMaximumPoolSize(2);
		DBInitHelper.executeSqlScript(ds,DatasourceConfig.class.getResourceAsStream("/db/schema-mysql.sql"));

		return ds;
	}

	/**
	 * 模拟一个包含多个数据库的动态数据源，实际多租户场景，还允许动态添加数据源（租户）
	 * @param h2
	 * @param mysql
	 * @return
	 */
	@Bean(name = "dynamicDs")
	public DynamicRoutingDataSource routing(@Qualifier("h2Ds") DataSource h2,@Qualifier("mysqlDs") DataSource mysql) {
		DynamicRoutingDataSourceAndSqlManager ds = new DynamicRoutingDataSourceAndSqlManager();
		ds.setDefaultTargetDataSource(h2);
		Map<Object,Object> map = new HashMap<>();
		map.put("h2Ds",h2);
		map.put("mysqlDs",mysql);
		ds.setTargetDataSources(map);
		return ds;
	}

	@Bean(name = "defaultTs")
	public DataSourceTransactionManager defaultTs(@Qualifier("dynamicDs") DataSource ds) {
		DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(ds);
		return dataSourceTransactionManager;
	}

	@Bean
	public SQLManagerCustomize mySQLManagerCustomize(@Qualifier("dynamicDs") DynamicRoutingDataSource routingDataSource){
		return new SQLManagerCustomize(){
			@Override
			public void customize(String sqlMangerName, SQLManager manager) {
				manager.setInters(new Interceptor[]{new MyDebug(routingDataSource)});
			}
		};
	}

	/**
	 * sql输出时候，同时打印数据源
	 */
	public class MyDebug extends DebugInterceptor {
		DynamicRoutingDataSource routingDataSource ;
		public MyDebug(DynamicRoutingDataSource routingDataSource ){
			this.routingDataSource = routingDataSource;
		}
		@Override
		protected String formatSqlId(ExecuteContext executeContext){
			String sql = "DB["+routingDataSource.determineCurrentLookupKey()+"]->"+super.formatSqlId(executeContext);
			return sql;

		}
	}
}
